package com.zetor.ms.core.util;

import com.zetor.ms.core.bo.Result;
import com.zetor.ms.core.enums.ResultState;
import org.springframework.util.StringUtils;

import java.util.Collection;

/**
 * 统一结果集封装
 *
 * @author zlc
 * @date 2021/12/27
 */
public class HisResultUtil {

	/**
	 * 判断 Result 是否返回成功
	 * @param result
	 * @param <T>
	 * @return
	 */
	public static <T> boolean isSuccess(Result<T> result) {
		return result.getHead().getStatus() == ResultState.SUCCESS.getKey();
	}

	/**
	 * 判断 Result 是否返回失败
	 * @param result
	 * @param <T>
	 * @return
	 */
	public static <T> boolean isFailure(Result<T> result) {
		return result.getHead().getStatus() == ResultState.FAIL.getKey();
	}

	/**
	 * 判断 Result 是否具有body值
	 * @param result
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> boolean hasBody(Result<T> result) {
		if (result.getBody() instanceof Collection) {
			Collection<? extends T> body = (Collection<? extends T>) result.getBody();
			return result.getBody() != null && !body.isEmpty();
		} else if (result.getBody() instanceof String) {
			String body = (String) result.getBody();
			return StringUtils.hasText(body);
		} else {
			return result.getBody() != null;
		}
	}

	private static <T> void setResult(Result<T> result, int state, String showMessage, String exceptionMessage, T body) {
		result.getHead().setStatus(state);
		result.getHead().setMessage(showMessage);
		result.getHead().setSysMessage(exceptionMessage);
		result.setBody(body);
	}

	/**
	 * 成功结果集封装
	 * @param result
	 * @param successMessage
	 * @param <T>
	 */
	public static <T> void success(Result<T> result, String successMessage) {
		setResult(result, ResultState.SUCCESS.getKey(), successMessage, "", null);
	}

	/**
	 * 成功结果集封装
	 * @param result
	 * @param successMessage
	 * @param body
	 * @param <T>
	 */
	public static <T> void success(Result<T> result, String successMessage, T body) {
		setResult(result, ResultState.SUCCESS.getKey(), successMessage, "", body);
	}

	/**
	 * 失败结果集封装
	 * @param result
	 * @param showMessage
	 * @param exceptionMessage
	 * @param <T>
	 */
	public static <T> void failure(Result<T> result, String showMessage, String exceptionMessage) {
		setResult(result, ResultState.FAIL.getKey(), showMessage, exceptionMessage, null);
	}

	/**
	 * 失败结果集封装
	 * @param result
	 * @param showMessage
	 * @param exceptionMessage
	 * @param body
	 * @param <T>
	 */
	public static <T> void failure(Result<T> result, String showMessage, String exceptionMessage, T body) {
		setResult(result, ResultState.FAIL.getKey(), showMessage, exceptionMessage, body);
	}

	/**
	 * 失败结果集封装
	 * @param result
	 * @param status
	 * @param showMessage
	 * @param exceptionMessage
	 * @param <T>
	 */
	public static <T> void failure(Result<T> result, int status, String showMessage, String exceptionMessage) {
		setResult(result, status, showMessage, exceptionMessage, null);
	}

	/**
	 * 成功结果集封装
	 * @param <T>
	 */
	public static <T> Result<T> succeed() {
		return succeed("", null);
	}

	/**
	 * 成功结果集封装
	 * @param msgCode
	 * @param <T>
	 */
	public static <T> Result<T> succeed(String msgCode) {
		return succeed(msgCode, null);
	}

	/**
	 * 成功结果集封装
	 * @param msgCode
	 * @param body
	 * @param <T>
	 */
	public static <T> Result<T> succeed(String msgCode, T body) {
		Result<T> result = new Result<>();
		result.getHead().setStatus(ResultState.SUCCESS.getKey());
		result.getHead().setMessage(MsgUtils.get(msgCode));
		result.setBody(body);
		return result;
	}

	/**
	 * 结果集封装
	 *
	 * @param msgCode 消息code，参考【messages.properties】配置文件
	 * @return
	 */
	public static <T> Result<T> failed(String msgCode) {
		return failed(msgCode, null, null, null);
	}

	/**
	 * 结果集封装
	 *
	 * @param msgCode 消息code，参考【messages.properties】配置文件
	 * @return
	 */
	public static <T> Result<T> failed(String msgCode, T body) {
		return failed(msgCode, "", body, null);
	}

	/**
	 * 构建请求失败对象,
	 *
	 * @param msgCode	消息码，参考【messages.properties】配置文件
	 * @param expMsg	系统异常信息
	 * @param <T>		数据对象类型
	 * @return Result
	 */
	public static <T> Result<T> failed(String msgCode, String expMsg, T body) {
		return failed(msgCode, expMsg, body, null);
	}

	/**
	 * 自定义消息错误返回
	 * @return
	 */
	public static <T> Result<T> failed(String msgCode, String expMsg, T body, String... args) {
		String msg = "";
		if (!StringUtils.isEmpty(msgCode)) {
			if (args != null) {
				msg = MsgUtils.get(msgCode, args);
			} else {
				msg = MsgUtils.get(msgCode);
			}
		}
		return failedMsg(msgCode, HisRandomUtil.getRandCode(), msg, expMsg, body);
	}

	/**
	 * 自定义消息错误返回
	 * @param msgCode 错误码
	 * @param sn 序列号
	 * @param msg 消息内容
	 * @param expMsg 异常消息内容
	 * @param body 数据实体
	 * @param <T>
	 * @return
	 */
	public static <T> Result<T> failedMsg(String msgCode, Integer sn, String msg, String expMsg, T body) {
		Result<T> result = new Result<>();
		String key = "";
		if (!StringUtils.isEmpty(msgCode)) {
			key = msgCode;
		}
		if (null == sn) {
			sn = HisRandomUtil.getRandCode();
		}
		LogUtils.error("{}:{}", sn, msg);
		result.getHead().setStatus(ResultState.FAIL.getKey());
		result.getHead().setMessage(msg);
		result.getHead().setSysMessage(expMsg);
		result.getHead().setSequence(sn);
		result.getHead().setKey(key);
		result.setBody(body);
		return result;
	}
}
